﻿using Domain.Entitys.Base_Manage;
using Domain.Entitys.DB;
using Domain.IRepositorys.DB;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EFCore.Repositorys.DB
{
    public class Db_Product_TypeRepository : IDb_Product_TypeRepository
    {
        private readonly MyDbContext _dbContext;

        public Db_Product_TypeRepository(MyDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        public List<Product_Type_Tree> GetProduct_Types(int currentPage, int pageSize, string typeName, char status)
        {
            // 1. 获取基础查询（未删除的数据）
            var baseQuery = _dbContext.Db_Product_Type
                .OrderBy(d => d.Pro_type_sort)
                .Where(pt => pt.Del_flag == '0');

            // 2. 应用过滤条件
            if (!string.IsNullOrEmpty(typeName))
            {
                baseQuery = baseQuery.Where(pt =>
                    pt.Pro_type_name.Contains(typeName) ||
                    pt.Pro_type_code.Contains(typeName));
            }

            if (status == '0' || status == '1')
            {
                baseQuery = baseQuery.Where(pt => pt.Pro_type_status == status);
            }

            // 3. 获取匹配的节点ID（去重）
            var matchedIds = baseQuery
                .Select(pt => pt.Pro_type_id)
                .Distinct()
                .ToList();

            if (!matchedIds.Any())
                return new List<Product_Type_Tree>();

            // 4. 查找所有子节点ID（向下递归，去重）
            var allChildIds = FindAllChildIds(matchedIds,status);

            // 5. 合并匹配节点及其子节点（使用HashSet自动去重）
            var relevantIds = new HashSet<int>(matchedIds);
            relevantIds.UnionWith(allChildIds);

            // 6. 获取所有相关节点数据（一次性查询）
            var relevantNodes = _dbContext.Db_Product_Type
                .Where(pt => relevantIds.Contains(pt.Pro_type_id))
                .ToList();

            // 7. 构建不重复的子树集合
            var resultTrees = new List<Product_Type_Tree>();
            var processedIds = new HashSet<int>(); // 跟踪已处理的节点

            foreach (var node in relevantNodes)
            {
                // 只处理匹配的节点，且未被处理过的
                if (matchedIds.Contains(node.Pro_type_id) && !processedIds.Contains(node.Pro_type_id))
                {
                    var tree = BuildSubTree(node, relevantNodes, processedIds);
                    if (tree != null)
                    {
                        resultTrees.Add(tree);
                    }
                }
            }

            if (currentPage == 0 && pageSize == 0)
            {
                return resultTrees;
            }
            else
            {
                // 8. 分页处理
                return resultTrees.OrderBy(pt => pt.Pro_type_sort)
                    .Skip((currentPage - 1) * pageSize)
                    .Take(pageSize)
                    .ToList();
            }
        }

        private List<int> FindAllChildIds(List<int> parentIds,char status)
        {
            var allChildIds = new HashSet<int>(); // 使用HashSet自动去重
            var currentLevel = new HashSet<int>(parentIds);

            while (currentLevel.Any())
            {
                var childIds = _dbContext.Db_Product_Type
                    .Where(pt => currentLevel.Contains(pt.Parent_id))
                    .Where(pt => pt.Del_flag == '0')
                    .Where(pt => pt.Pro_type_status == status)
                    .Select(pt => pt.Pro_type_id)
                    .Distinct()
                    .ToList();

                var newChildIds = childIds.Where(id => !allChildIds.Contains(id)).ToList();
                if (!newChildIds.Any()) break;

                allChildIds.UnionWith(newChildIds);
                currentLevel = new HashSet<int>(newChildIds);
            }

            return allChildIds.ToList();
        }

        private Product_Type_Tree BuildSubTree(Db_Product_Type node, List<Db_Product_Type> allNodes, HashSet<int> processedIds)
        {
            // 如果节点已处理，返回null（避免重复）
            if (processedIds.Contains(node.Pro_type_id))
                return null;

            // 标记节点为已处理
            processedIds.Add(node.Pro_type_id);

            var treeNode = new Product_Type_Tree
            {
                Pro_type_id = node.Pro_type_id,
                Pro_type_name = node.Pro_type_name,
                Pro_type_code = node.Pro_type_code,
                Pro_type_sort = node.Pro_type_sort,
                Parent_id = node.Parent_id,
                Pro_type_status = node.Pro_type_status,
                Del_flag = node.Del_flag,
                Create_by = node.Create_by,
                Create_time = node.Create_time,
                children = allNodes
                    .Where(n => n.Parent_id == node.Pro_type_id).OrderBy(n => n.Pro_type_sort)
                    .Select(n => BuildSubTree(n, allNodes, processedIds))
                    .Where(t => t != null) // 过滤掉null（已处理的节点）
                    .ToList()
            };

            return treeNode;
        }

        /// <summary>
        /// 条件查询产品类型数量
        /// </summary>
        /// <param name="typeName"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public int Product_TypeCount(string typeName, char status)
        {
            var baseQuery = _dbContext.Db_Product_Type
                .Where(pt => pt.Del_flag == '0');

            if (!string.IsNullOrEmpty(typeName))
            {
                baseQuery = baseQuery.Where(pt =>
                    pt.Pro_type_name.Contains(typeName) ||
                    pt.Pro_type_code.Contains(typeName));
            }

            if (status == '0' || status == '1')
            {
                baseQuery = baseQuery.Where(pt => pt.Pro_type_status == status);
            }

            var matchedIds = baseQuery
                .Select(pt => pt.Pro_type_id)
                .Distinct()
                .ToList();

            if (!matchedIds.Any())
                return 0;

            var allChildIds = FindAllChildIds(matchedIds, status);
            var relevantIds = new HashSet<int>(matchedIds);
            relevantIds.UnionWith(allChildIds);

            return relevantIds.Count;
        }

        /// <summary>
        /// 检查同一分类下序号是不是唯一
        /// </summary>
        /// <param name="sort"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public bool CheckSortUnique(int sort, int parentId,int proTypeId)
        {
            return !_dbContext.Db_Product_Type
                .Where(pt => pt.Parent_id == parentId)
                .Where(pt => pt.Pro_type_sort == sort)
                .Where(PT => PT.Pro_type_id != proTypeId).Any();
        }

        /// <summary>
        /// 添加产品分类信息
        /// </summary>
        /// <param name="db_Product_Type"></param>
        /// <returns></returns>
        public async Task<int> Product_TypeAddAsync(Db_Product_Type db_Product_Type)
        {
            await _dbContext.Db_Product_Type.AddAsync(db_Product_Type);
            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 修改产品分类信息
        /// </summary>
        /// <param name="db_Product_Type"></param>
        /// <returns></returns>
        public async Task<int> Product_TypeUpdateAsync(Db_Product_Type db_Product_Type)
        {
            Db_Product_Type db_Product_Type1 = _dbContext.Db_Product_Type.FirstOrDefault(pt => pt.Pro_type_id == db_Product_Type.Pro_type_id);
            db_Product_Type1.Pro_type_name = db_Product_Type.Pro_type_name;
            db_Product_Type1.Pro_type_code = db_Product_Type.Pro_type_code;
            db_Product_Type1.Pro_type_sort = db_Product_Type.Pro_type_sort;
            db_Product_Type1.Parent_id = db_Product_Type.Parent_id;
            db_Product_Type1.Pro_type_status = db_Product_Type.Pro_type_status;
            db_Product_Type1.Update_by = db_Product_Type.Update_by;
            db_Product_Type1.Update_time = db_Product_Type.Update_time;
            _dbContext.Update(db_Product_Type1);
            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 逻辑删除产品分类信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Product_TypeDeleteAsync(List<Db_Product_Type> db_Product_Type)
        {
            List<Db_Product_Type> db_Product_Types = new List<Db_Product_Type>();
            foreach (var item in db_Product_Type)
            {
                Db_Product_Type db_Product_Type1 = _dbContext.Db_Product_Type.FirstOrDefault(pt => pt.Pro_type_id == item.Pro_type_id);
                db_Product_Type1.Del_flag = item.Del_flag;
                db_Product_Types.Add(db_Product_Type1);
            }
            _dbContext.UpdateRange(db_Product_Types);
            return await _dbContext.SaveChangesAsync();
        }
    }
}